module CanCamel
  module Cache
    class <<self
      delegate :[], to: :cache

      def reload!
        @cache = build_cache
        inherit_all!
      end

      def children_of(node)
        return [] unless node
        cache.select do |path, _value|
          _, *subpath = path
          node.path == subpath
        end.values
      end

      def append(node, path)
        path = [node.name, *path]
        old = @cache[path]

        if old
          old.inherit! node
        else
          new = node.dup
          new.path = path
          @cache[path] = new
          children_of(node).each { |child| append child, path }
        end
      end

      private

      # def subpath?(path, subpath)
      #   return if path.empty?
      #   return true if subpath.empty?
      #   return unless path[-1] == subpath[-1]
      #   subpath?(path[0...-1], subpath[0...-1])
      # end

      def cache
        @cache || (reload!; @cache)
      end

      def build_cache
        Node.all.each_with_object({}) do |node, object|
          object[node.path] = node
        end.merge([] => Root.new)
      end

      def inherit_all!
        local_cache = cache.dup
        local_cache.each { |_path, node| node.inherit! }
      end
    end
  end
end
